import { BehaviorSubject, Subject, takeUntil, timer } from "rxjs";

// 场景：用户身份认证服务
class AuthService {
  // 创建 BehaviorSubject 并设置初始值 (未登录状态)
  // 类型为 { isLoggedIn: boolean; username?: string }
  private authState = new BehaviorSubject<{
    isLoggedIn: boolean;
    username?: string;
  }>({
    isLoggedIn: false,
  });

  // 公开的只读 Observable (外部组件只能订阅，不能直接修改状态)
  authState$ = this.authState.asObservable();

  // 登录方法
  login(username: string) {
    this.authState.next({
      isLoggedIn: true,
      username,
    });
    console.log(`用户 ${username} 已登录`);
  }

  // 登出方法
  logout() {
    this.authState.next({
      isLoggedIn: false,
    });
    console.log("用户已登出");
  }

  // 获取当前状态快照 (无需订阅)
  getCurrentState() {
    return this.authState.getValue();
  }
}

run();
function run() {
  // 使用示例
  // 创建销毁控制器（用于取消订阅）, 当作信号使用
  const destroy$ = new Subject<void>();

  const authService = new AuthService();

  // 组件A：订阅认证状态变化
  const subscriptionA = authService.authState$.subscribe((state) => {
    console.log(
      "[组件A] 认证状态更新:",
      state.isLoggedIn ? `已登录用户: ${state.username}` : "未登录",
    );
  });

  // 组件B：获取当前状态快照
  console.log("[组件B] 当前状态:", authService.getCurrentState());

  // / call timer
  timer(1000)
    .pipe(takeUntil(destroy$))
    .subscribe(() => {
      authService.login("Alice");
    });

  timer(3000)
    .pipe(takeUntil(destroy$))
    .subscribe(() => {
      authService.logout();
    });

  // 4秒后取消所有订阅并销毁
  timer(4000)
    .pipe(takeUntil(destroy$))
    .subscribe(() => {
      console.log("[组件A] 已取消订阅");
      subscriptionA.unsubscribe();

      // 发出销毁信号
      destroy$.next();
      destroy$.complete();
    });

  // 添加最终清理（可选）
  timer(5000).subscribe(() => {
    console.log("所有操作完成");
  });
}

export class BestPractice<StateType> {
  constructor(private initialState: StateType) {}

  // 推荐将 Subject 设为私有，通过以下方式控制访问：
  private _state = new BehaviorSubject(this.initialState);

  // 1. 对外暴露只读 Observable
  state$ = this._state.asObservable();

  // 2. 提供修改状态的方法（集中管理状态变更）
  updateState(newState: Partial<StateType>) {
    this._state.next({ ...this._state.getValue(), ...newState });
  }

  // 3. 提供安全的状态获取方式
  get currentState() {
    return this._state.getValue();
  }
}
